<template>
  <div class="main-wrapper flex-column">
    <!-- 搜索区 -->
    <div class="search-bar flex-row flex-center">
      <div class="title">个人信息</div>
      <div class="clear"></div>
      <div class="operation"></div>
    </div>

    <!-- 表单区 -->
    <div class="main-table-area">
      <a-card class="user-panel">
        <div class="user-info flex-row">
          <div class="left-info flex-column">
            <div class="user-avatar">
              <a-avatar :size="140">
                <template #icon>
                  <img v-if="uploadBase64 && uploadBase64 !== ''"
                    :src="uploadBase64" crossorigin="anonymous" style="width: 100%; height: 100%;" />
                  <img v-else-if="storeUserInfo.userInfo.avatar && storeUserInfo.userInfo.avatar !== ''"
                    :src="storeUserInfo.userInfo.avatar" crossorigin="anonymous" style="width: 100%; height: 100%;" />
                  <img v-else
                    src="@/assets/images/default-big.png" style="width: 100%; height: 100%;" />
                </template>
              </a-avatar>
              <div class="edit-avatar">
                <a-upload
                  v-model:file-list="uploadList"
                  name="file"
                  :show-upload-list="false"
                  :action="uploadAction"
                  :headers="uploadHeaders"
                  :before-upload="beforeUpload"
                  @change="handleUpload"
                >
                  <img src="./img/edit.png" style="cursor: pointer; width: 100%; height: 100%;" />
                </a-upload>
              </div>
            </div>
            <div class="avatar-tip">推荐尺寸200x200，支持jpg、jpeg、png格式，大小不超过1MB</div>
          </div>
          <div class="space"></div>
          <div class="right-info flex-column">
            <div class="sex-title">性别</div>
            <div class="sex-value">
              <a-select
                ref="selectSex"
                v-model:value="sexValue"
                :options="sexOptions"
                @change="changeSex"
                placeholder="请选择"
                style="width: 210px"
              ></a-select>
            </div>
            <div class="location-title">所在地</div>
            <div class="location-value flex-row">
              <div style="width: 230px;">
                <a-select
                  ref="selectProvince"
                  v-model:value="provinceValue"
                  placeholder="请选择"
                  :options="provinceOptions"
                  @change="changeProvince"
                  style="width: 210px;"
                ></a-select>
              </div>
              <div style="width: 230px;">
                <a-select
                  ref="selectCity"
                  v-model:value="cityValue"
                  placeholder="请选择"
                  :options="cityOptions"
                  @change="changeCity"
                  style="width: 210px;"
                ></a-select>
              </div>
              <div style="width: 230px;">
                <a-select
                  ref="selectCounty"
                  v-model:value="countyValue"
                  placeholder="请选择"
                  :options="countyOptions"
                  @change="changeCounty"
                  style="width: 210px;"
                ></a-select>
              </div>
            </div>
            <div class="memo-title">自我介绍</div>
            <div class="memo-value">
              <a-textarea v-model:value="storeUserInfo.userInfo.bio" style="height: 100%;" />
            </div>
            <div class="button-confirm">
              <a-button type="primary" shape="round" size="large"
                @click="updateUserInfo"
                style="padding: 0 40px;">
                确认修改
              </a-button>
            </div>
          </div>
        </div>
      </a-card>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onBeforeMount } from 'vue';
import { message } from 'ant-design-vue';
import type { SelectProps, UploadChangeParam, UploadProps } from 'ant-design-vue';
import useUserInfoStore from "@/stores/user-info";
import useAppStore from "@/stores/app";
import appConfig from "@/config";
import { UserInfo } from '@/models/user';
import { getText } from '@/utils';
import { miscApi } from "@/services";

const sexValue = ref('');
const sexOptions = ref<SelectProps['options']>([
  { value: '', label: '请选择' },
  { value: '1', label: '男' },
  { value: '2', label: '女' },
]);

const provinceOptions = ref<SelectProps['options']>([{ value: '', label: '请选择' }]);
const provinceValue = ref('');

const cityOptions = ref<SelectProps['options']>([{ value: '', label: '请选择' }]);
const cityValue = ref('');

const countyOptions = ref<SelectProps['options']>([{ value: '', label: '请选择' }]);
const countyValue = ref('');

const changeSex: SelectProps['onChange'] = value => {
  console.log("changeSex value: ", value);
  sexValue.value = getText(value);
};

const changeProvince: SelectProps['onChange'] = value => {
  console.log("changeProvince value: ", value);
  provinceValue.value = getText(value);

  let cities = [{ value: '', label: '请选择' }];
  if (value) {
    for (let i = 0; i < storeUserInfo.areaList.length; i++) {
      let province = storeUserInfo.areaList[i];
      if (provinceValue.value === getText(province.areaId)) {
        for (let j = 0; j < province.children.length; j++) {
          let city = province.children[j];
          cities.push({ value: ''+city.areaId, label: city.name });
        }
        break;
      }
    }
  }
  cityOptions.value = cities;
  cityValue.value = '';
  countyOptions.value = [{ value: '', label: '请选择' }];
  countyValue.value = '';
};

const changeCity: SelectProps['onChange'] = value => {
  console.log("changeCity value: ", value);
  cityValue.value = getText(value);

  let counties = [{ value: '', label: '请选择' }];
  for (let i = 0; i < storeUserInfo.areaList.length; i++) {
    let province = storeUserInfo.areaList[i];
    if (provinceValue.value === getText(province.areaId)) {
      for (let j = 0; j < province.children.length; j++) {
        let city = province.children[j];
        if (cityValue.value === getText(city.areaId)) {
          for (let k=0; k < city.children.length; k++) {
            let county = city.children[k];
            counties.push({ value: ''+county.areaId, label: county.name });
          }
          break;
        }
      }
      break;
    }
  }
  countyOptions.value = counties;
  countyValue.value = '';
};

const changeCounty: SelectProps['onChange'] = value => {
  console.log("changeCounty value: ", value);
  countyValue.value = getText(value);
};

const storeUserInfo = useUserInfoStore();
onBeforeMount(async () => {
  await storeUserInfo.initData()

  if (storeUserInfo.userInfo) {
    sexValue.value = getText(storeUserInfo.userInfo.sex);
    if (storeUserInfo.userInfo.area) {
      provinceValue.value = getText(storeUserInfo.userInfo.area.provincesCode);
      cityValue.value = getText(storeUserInfo.userInfo.area.cityCode);
      countyValue.value = getText(storeUserInfo.userInfo.area.countyCode);
    } else {
      provinceValue.value = '';
      cityValue.value = '';
      countyValue.value = '';
    }
  } else {
    sexValue.value = '';
    provinceValue.value = '';
    cityValue.value = '';
    countyValue.value = '';
  }

  // 初始化省市县区数据
  if (storeUserInfo.areaList && storeUserInfo.areaList.length > 0) {
    let provinces = [{ value: '', label: '请选择' }];
    let cities = [{ value: '', label: '请选择' }];
    let counties = [{ value: '', label: '请选择' }];
    for (let i = 0; i < storeUserInfo.areaList.length; i++) {
      let province = storeUserInfo.areaList[i];
      provinces.push({ value: ''+province.areaId, label: province.name });

      if (provinceValue.value === getText(province.areaId)) {
        for (let j = 0; j < province.children.length; j++) {
          let city = province.children[j];
          cities.push({ value: ''+city.areaId, label: city.name });

          if (cityValue.value === getText(city.areaId)) {
            for (let k=0; k < city.children.length; k++) {
              let county = city.children[k];
              counties.push({ value: ''+county.areaId, label: county.name });
            }
          }
        }
      }
    }

    provinceOptions.value = provinces;
    cityOptions.value = cities;
    countyOptions.value = counties;
  }

  await miscApi.traceViewPage("/user-info/index");
});

// 上传URL
const uploadAction = appConfig.baseUrl + '/misc/upload';
// 上传头信息
const uploadHeaders = {
  'Access-Token': appConfig.apiToken,
};
// 上传文件列表
const uploadList = ref([]);
// 上传状态
const uploadLoading = ref<boolean>(false);
// 上传后的文件在服务端的URL
const uploadUrl = ref<string>('');
// 上传后的图片base64
const uploadBase64 = ref<string>('');

function getBase64(img: Blob, callback: (base64Url: string) => void) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result as string));
  reader.readAsDataURL(img);
}

const handleUpload = (info: UploadChangeParam) => {
  console.log("upload info: ", info);
  if (info.file.status === 'uploading') {
    uploadLoading.value = true;
    return;
  }
  if (info.file.status === 'done') {
    // Get this url from response in real world.
    getBase64(info.file.originFileObj, (base64Url: string) => {
      uploadBase64.value = base64Url;
      uploadLoading.value = false;
    });
    
    if(info.file.response && info.file.response.data) {
      uploadUrl.value = info.file.response.data;
    };
  }
  if (info.file.status === 'error') {
    uploadLoading.value = false;
    message.error('头像图片上传失败');
    return;
  }
};

const beforeUpload = (file: UploadProps['fileList'][number]) => {
  const isJpgOrPng = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('只能上传jpg、jpeg、png格式图片!');
    return false;
  }
  const isLimit = file.size / 1024 / 1024 <= 1;
  if (!isLimit) {
    message.error('上传图片的大小不能超过1MB!');
    return false;
  }
  return isJpgOrPng && isLimit;
};

const storeApp = useAppStore();
const updateUserInfo = () => {
  if (!sexValue.value) {
    message.error('请选择性别');
    return;
  }
  if (!provinceValue.value) {
    message.error('请选择省');
    return;
  }
  if (!cityValue.value) {
    message.error('请选择市');
    return;
  }
  if (!countyValue.value) {
    message.error('请选择县/区');
    return;
  }
  
  storeUserInfo.updateUserInfo({
    sex: parseInt(sexValue.value),
    area: {
      provincesCode: provinceValue.value,
      cityCode: cityValue.value,
      countyCode: countyValue.value,
    },
    avatar: uploadUrl.value ? uploadUrl.value : storeUserInfo.userInfo?.avatar,
    bio: storeUserInfo.userInfo.bio,
  } as UserInfo).then(() => {
    message.success('个人信息修改成功');

    // 修改成功更新store
    storeUserInfo.userInfo.sex = parseInt(sexValue.value);
    storeUserInfo.userInfo.area = {
      provincesCode: provinceValue.value,
      cityCode: cityValue.value,
      countyCode: countyValue.value,
    };
    storeUserInfo.userInfo.avatar = uploadUrl.value ? uploadUrl.value : storeUserInfo.userInfo.avatar;
    
    // 修改成功更新本地缓存
    storeApp.setUserInfo(storeUserInfo.userInfo);
  }).catch(() => {
    message.error('个人信息修改失败');
  });
};
</script>

<style lang="less" scoped>
.main-wrapper {
  display: flex;
  margin: 20px 30px;
  flex-direction: column;
  background-color: @white-bg;
  border-radius: 20px;

  .search-bar {
    width: 100%;

    .title {
      height: 24px;
      line-height: 24px;
      font-size: 20px;
      font-weight: 500;
      color: @font-black;
    }

    .clear {
      margin-left: 10px;
    }

    .operation {
      flex: 1;
    }
  }

  .custom-table {
    background-color: @pink-table-hd; /* 粉色背景颜色 */
    width: 100%;
  }

  .pagination-bar {
    display: flex;
    align-items: center;
    margin: 10px;
    border-spacing: 10px;
  }

  .main-table-area {
    margin-top: 20px;
    width: 100%;

    .user-panel {
      padding-bottom: 30px;

      .user-info {
        width: 100%;
        display: flex;

        .left-info {
          width: 140px;
          padding: 10px 0;

          .user-avatar {
            width: 140px;
            height: 140px;
          }

          .edit-avatar {
            position: absolute;
            float: left;
            top: 135px;
            left: 135px;
          }

          .avatar-tip {
            width: 100%;
            height: 54px;
            line-height: 18px;
            font-size: 12px;
            font-weight: 400;
            color: @font-grey-light;
            text-align: center;
            margin-top: 20px;
          }
        }

        .space {
          width: 90px;
        }

        .right-info {
          flex: 1;

          .sex-title, .location-title, .memo-title {
            height: 20px;
            line-height: 20px;
            font-size: 16px;
            font-weight: 500;
            color: @font-black;
            margin: 6px 0;
          }

          .location-title, .memo-title {
            margin-top: 30px;
          }

          .sex-value, .location-value {
            height: 44px;
            margin-top: 8px;
          }

          .memo-value {
            height: 200px;
            margin-top: 8px;
            border-radius: 22px;
          }

          .button-confirm {
            height: 44px;
            margin-top: 20px;
            text-align: right;
          }
        }
      }
    }
  }
}
.ant-table-thead {
  background-color: @pink-table-hd; /* 粉色背景颜色 */
  color: @white;
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  height: 24px;
  border-radius: 20px;
  padding: 10px;
  margin: 0;
  width: 100%;
  text-align: center;
  .ant-table-cell {
    background: @pink-table-hd;
  }
}
.ant-table-wrapper .ant-table-thead >tr>th {
  background: @pink-table-hd;
}
:deep(.ant-select-single:not(.ant-select-customize-input) .ant-select-selector) {
  height: 44px;
  padding: 0 32px 0 20px;  
}
:deep(.ant-select-single .ant-select-selector .ant-select-selection-item, .ant-select-single .ant-select-selector .ant-select-selection-placeholder) {
  line-height: 44px;
}
:deep(.ant-select-single .ant-select-selector) {
  font-size: 16px;
  border-radius: 22px;
}
:deep(.ant-select .ant-select-arrow) {
  padding-right: 8px;
}
textarea {
  border-radius: 22px;
  padding: 20px;
  font-size: 16px;
}
</style>
